package zsc.ruanc.practicaltraining.exception.handler;

import lombok.extern.slf4j.Slf4j;
import org.springframework.validation.BindingResult;
import org.springframework.validation.FieldError;
import org.springframework.web.bind.MethodArgumentNotValidException;
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.bind.annotation.RestControllerAdvice;
import org.springframework.web.multipart.MultipartException;
import zsc.ruanc.practicaltraining.exception.ApiException;
import zsc.ruanc.practicaltraining.model.result.JsonResult;
import zsc.ruanc.practicaltraining.model.result.ResultCode;
import zsc.ruanc.practicaltraining.utils.ResultUtils;

import javax.validation.ConstraintViolation;
import javax.validation.ConstraintViolationException;
import java.util.*;

/**
 * 全局异常处理类 所有的异常都在这里处理
 */
@RestControllerAdvice
@Slf4j
public class GlobalExceptionHandler {

    @ExceptionHandler(value = ApiException.class)
    public JsonResult ApiCatch(ApiException e) {
        ResultCode a = ResultCode.findCode(e.getCode());
        log.info("调用接口时发生错误: " + a.getCode() + " " + a.getMsg() + " "+ e.getInfo() + "   位置: " + e.getPosition());
        return ResultUtils.error(e.getCode(), e.getInfo());
    }

    // 数据校验错误
    @ExceptionHandler(value = MethodArgumentNotValidException.class)
    public JsonResult MethodArgumentNotValidException(MethodArgumentNotValidException e) {
        BindingResult bindingResult = e.getBindingResult();
        StringBuilder stringBuilder = new StringBuilder();
        for (FieldError i : bindingResult.getFieldErrors()) {
            stringBuilder.append(i.getDefaultMessage() + ',');
        }
        return ResultUtils.error(400, stringBuilder.toString());
    }


    // 文件超过限制异常
    @ExceptionHandler(MultipartException.class)
    public JsonResult MultipartException(MultipartException e) {
        return ResultUtils.error(-12, "文件不能超过20MB");
    }

    // 对get请求校验的异常
    @ExceptionHandler(ConstraintViolationException.class)
    public JsonResult ConstraintViolationException(ConstraintViolationException e) {
        Set<ConstraintViolation<?>> constraintViolations = e.getConstraintViolations();
        Iterator<ConstraintViolation<?>> iterator = constraintViolations.iterator();
        List<String> msgList = new ArrayList<>();
        while (iterator.hasNext()) {
            ConstraintViolation<?> cvl = iterator.next();
            msgList.add(cvl.getMessageTemplate());
        }
        return ResultUtils.error(400, msgList);
    }

}
